#ifndef __MODEL_HH__
#define __MODEL_HH__

#include <iostream>
#include <map>
#include <utility>
#include <vector>
using namespace std;

#include "Bitext.hh"

/**
 * Defines alignment expected counts: access in order (source, target).
 */
class ExpectedCounts : public vector<vector<double> >{
public:
  ExpectedCounts(){
    I = J = 0;
  }
  ExpectedCounts(SentencePair &pair){
    reset(pair);
  }
  /**
   * Prepares the data structure for a new pair: resize, set zero counts.
   */
  void reset(SentencePair &);
  /**
   * Output the expected counts to standard out.
   */
  void print();
  /**
   * Retrieve number of target words.
   */
  int get_I(){ return I; }
  /**
   * Retrieve number of source words.
   */
  int get_J(){ return J; }
private:
  int I, J;
};

/**
 * Defines the behavior of a word alignment model.
 */
class Model{
public:
  /**
   * Transfer into this model from another model.
   */
  virtual void transfer(Bitext &, Model *){
    cerr << get_model_name() << " does not support transfer" << endl;
    exit(1);
  }
  /**
   * Get expected counts of alignments for sentence pair.
   */
  void get_expected_counts(Bitext &, SentencePair &, ExpectedCounts &);
  /**
   * Get the name of the model.
   */
  virtual string get_model_name(){
    cerr << "get_model_name() called on virtual Model!" << endl;
    exit(1);
  }
  /**
   * Initiates one training iteration.
   */
  virtual void iterate(Bitext &) = 0;
  /**
   * Finds the most probable alignment and dumps to file.
   */
  virtual double viterbi(SentencePair &, bool);

private:
  virtual double viterbi_inner(SentencePair &, bool){
    cerr << get_model_name() << " does not support viterbi decoding" << endl;
    exit(1);
  }

  /**
   * Get raw expected counts of alignments for sentence pair.
   */
  virtual void get_raw_expected_counts(Bitext &, SentencePair &, ExpectedCounts &){
    cerr << get_model_name() << " does not support expected counts" << endl;
    exit(1);
  }
};

#endif
